import {PromiseFunc} from './types';

export function composePromise<T, V>(promiseFuncs: Array<PromiseFunc<any, any>>): PromiseFunc<T, V> {
    return (singleArg: T) => {
        return promiseFuncs.reduce((promiseP: Promise<any>, promiseFunc) => promiseP.then(promiseFunc), Promise.resolve(singleArg));
    };
}

export function concurrentPromise<T>(promiseFuncs: Array<PromiseFunc<any, any>>): PromiseFunc<T, any[]> {
    return (singleArg: T) => {
        const promises = promiseFuncs.map((promiseFunc) => promiseFunc(singleArg));
        return Promise.all(promises);
    };
}

/**
 * promise串行操作的async版本
 * @param promiseFuncs 一元返回Promise实例的方法
 */
export function asynComposePromise<T, V>(promiseFuncs: Array<PromiseFunc<any, any>>): PromiseFunc<T, V> {
    return async (singleArg: T) => {
        let res: any = singleArg;
        for (const promiseFunc of promiseFuncs) {
            res = await promiseFunc(res);
        }
        return res as V;
    };
}

export function asyncConcurrentPromise<T>(promiseFuncs: Array<PromiseFunc<any, any>>): PromiseFunc<T, any> {
    return async (singleArg: T) => {
        return Promise.all(promiseFuncs.map(async (promiseFunc) => await promiseFunc(singleArg)));
    };
}
